using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using MEA.AE_Data;

namespace MEA.Chart
{
	public class Koordsyst
	{
		public Matrix toBild;

		public Matrix toWert;

		private RectangleF Wert;

		private PointF[] pp;

		private PointF[] center;

		private Font fnt;

		private float xmin;

		private float xmax;

		private float ymin;

		private float ymax;

		private float xlen;

		private float ylen;

		private double xscal;

		private double yscal;

		private int width;

		private int height;

		private Pen p;

		private Pen p_raster;

		private bool show_xraster;

		private bool show_xscalierung;

		private bool show_xaxe;

		private bool always_xaxe;

		private bool show_yraster;

		private bool show_yscalierung;

		private bool show_yaxe;

		private bool always_yaxe;

		private SolidBrush fnt_brush;

		private SolidBrush fnt_brush_x;

		private float xaxeoffset_bild;

		private float yaxeoffset_bild;

		private float xaxeoffset;

		private float yaxeoffset;

		private string x_axetext;

		private string y_axetext;

		private ConfigBase.EStringFormat format;

		public object koordvar;

		public ConfigBase.EStringFormat Format
		{
			get
			{
				return format;
			}
		}

		[Category("Style")]
		[Description("Font of the Coordinatesystem")]
		public Font KoordFont
		{
			get
			{
				return fnt;
			}
			set
			{
				fnt = value;
			}
		}

		[Category("X-axe")]
		[Description("x-Grid of the Coordinatesystem")]
		public bool XKoordRaster
		{
			get
			{
				return show_xraster;
			}
			set
			{
				show_xraster = value;
			}
		}

		[Browsable(false)]
		[Category("X-axe")]
		[Description("x-Scaling of the Coordinatesystem")]
		public bool XKoordSkalierung
		{
			get
			{
				return show_xscalierung;
			}
			set
			{
				show_xscalierung = value;
			}
		}

		[Description("view x-axe")]
		[Category("X-axe")]
		public bool XAxe
		{
			get
			{
				return show_xaxe;
			}
			set
			{
				show_xaxe = value;
			}
		}

		[Description("view y-axe")]
		[Category("Y-axe")]
		public bool YAxe
		{
			get
			{
				return show_yaxe;
			}
			set
			{
				show_yaxe = value;
			}
		}

		[Description("always show x-axe")]
		[Category("X-axe")]
		public bool AlwaysXAxe
		{
			get
			{
				return always_xaxe;
			}
			set
			{
				always_xaxe = value;
			}
		}

		[Category("Y-axe")]
		[Description("y-Grid of the Coordinatesystem")]
		public bool YKoordRaster
		{
			get
			{
				return show_yraster;
			}
			set
			{
				show_yraster = value;
			}
		}

		[Browsable(false)]
		public bool YKoordSkalierung
		{
			get
			{
				return show_yscalierung;
			}
			set
			{
				show_yscalierung = value;
			}
		}

		[Browsable(false)]
		public bool YKoordAxes
		{
			get
			{
				return show_yaxe;
			}
			set
			{
				show_yaxe = value;
			}
		}

		[Category("Y-axe")]
		[Description("always show y-axe")]
		public bool AlwaysYAxe
		{
			get
			{
				return always_yaxe;
			}
			set
			{
				always_yaxe = value;
			}
		}

		[Description("Color of the grid")]
		[Category("Style")]
		public Color RasterColor
		{
			get
			{
				return p_raster.Color;
			}
			set
			{
				p_raster.Color = value;
			}
		}

		[Category("Style")]
		[Description("Color of the Coordinatesystem")]
		public Color KoordColor
		{
			get
			{
				return p.Color;
			}
			set
			{
				p.Color = value;
				fnt_brush.Color = value;
			}
		}

		[Description("x-axe text")]
		[Category("X-axe")]
		public string XAxeText
		{
			get
			{
				return x_axetext;
			}
			set
			{
				x_axetext = value;
			}
		}

		[Description("y-axe text")]
		[Category("Y-axe")]
		public string YAxeText
		{
			get
			{
				return y_axetext;
			}
			set
			{
				y_axetext = value;
			}
		}

		[Category("Skalierung")]
		[Description("Scaling of the x-axe")]
		public double XScal
		{
			get
			{
				return xscal;
			}
			set
			{
				if (value > 0.0)
				{
					xscal = value;
				}
			}
		}

		[Category("Skalierung")]
		[Description("Scaling of the y-axe")]
		public double YScal
		{
			get
			{
				return yscal;
			}
			set
			{
				if (value > 0.0)
				{
					yscal = value;
				}
			}
		}

		[Description("Start of the x-axe")]
		[Category("Data")]
		public float XMin
		{
			get
			{
				return xmin;
			}
			set
			{
				if (value < xmax)
				{
					xmin = value;
					updateMatrix();
				}
			}
		}

		[Description("End of the x-axe")]
		[Category("Data")]
		public float XMax
		{
			get
			{
				return xmax;
			}
			set
			{
				if (value > xmin)
				{
					xmax = value;
					updateMatrix();
				}
			}
		}

		[Category("Data")]
		[Description("Start of the y-axe")]
		public float YMin
		{
			get
			{
				return ymin;
			}
			set
			{
				if (value < ymax)
				{
					ymin = value;
					updateMatrix();
				}
			}
		}

		[Description("End of the y-axe")]
		[Category("Data")]
		public float YMax
		{
			get
			{
				return ymax;
			}
			set
			{
				if (value > ymin)
				{
					ymax = value;
					updateMatrix();
				}
			}
		}

		[Browsable(false)]
		public float XLen
		{
			get
			{
				return xlen;
			}
		}

		[Browsable(false)]
		public float YLen
		{
			get
			{
				return ylen;
			}
		}

		[Browsable(false)]
		public int BILD_WIDTH
		{
			get
			{
				return width;
			}
			set
			{
				width = value;
				updateMatrix();
			}
		}

		[Browsable(false)]
		public int BILD_HEIGHT
		{
			get
			{
				return height;
			}
			set
			{
				height = value;
				updateMatrix();
			}
		}

		[Browsable(false)]
		public PointF Offset
		{
			get
			{
				return pp[0];
			}
			set
			{
				pp[0] = new PointF(value.X, value.Y);
				updateMatrix();
			}
		}

		[Description("Offset of the x-axe")]
		[Category("Data")]
		public float XAxeOffset
		{
			get
			{
				return xaxeoffset_bild;
			}
			set
			{
				xaxeoffset_bild = value;
			}
		}

		[Category("Data")]
		[Description("Offset of the y-axe")]
		public float YAxeOffset
		{
			get
			{
				return yaxeoffset_bild;
			}
			set
			{
				yaxeoffset_bild = value;
			}
		}

		public Koordsyst(Size Bild, float xmin, float xmax, float ymin, float ymax, int xoffset, ConfigBase.EStringFormat format)
		{
			Wert = new RectangleF(xmin, ymax, xmax - xmin, (ymax - ymin) * -1f);
			this.format = format;
			xlen = Wert.Width;
			ylen = Math.Abs(Wert.Height);
			this.xmin = xmin;
			this.xmax = xmax;
			this.ymin = ymin;
			this.ymax = ymax;
			width = Bild.Width;
			height = Bild.Height;
			pp = new PointF[3];
			pp[0] = new PointF(xoffset, 25f);
			pp[1] = new PointF(Bild.Width - xoffset, 25f);
			pp[2] = new PointF(xoffset, Bild.Height - 25);
			toBild = new Matrix(Wert, pp);
			center = new PointF[1];
			center[0] = new PointF(0f, 0f);
			toBild.TransformPoints(center);
			toWert = toBild.Clone();
			toWert.Invert();
			fnt = new Font(FontFamily.GenericSansSerif, 8f);
			p = new Pen(Color.Black, 1f);
			p_raster = new Pen(Color.DimGray, 1f);
			p_raster.DashStyle = DashStyle.Dash;
			fnt_brush = new SolidBrush(Color.Black);
			fnt_brush_x = new SolidBrush(Color.Black);
			show_xscalierung = true;
			show_xaxe = true;
			show_yscalierung = true;
			show_yaxe = true;
			x_axetext = "s";
			y_axetext = "y";
			Autoscale();
		}

		public PointF transformToBild(float x, float y)
		{
			PointF[] array = new PointF[1]
			{
				new PointF(x, y)
			};
			lock (toBild)
			{
				lock (toWert)
				{
					toBild.TransformPoints(array);
				}
			}
			return array[0];
		}

		public PointF transformToBild(PointF[] p)
		{
			lock (toBild)
			{
				lock (toWert)
				{
					toBild.TransformPoints(p);
				}
			}
			return p[0];
		}

		public PointF transformToWert(int x, int y)
		{
			PointF[] array = new PointF[1]
			{
				new PointF(x, y)
			};
			lock (toBild)
			{
				lock (toWert)
				{
					toWert.TransformPoints(array);
				}
			}
			return array[0];
		}

		public PointF transformToWert(PointF[] p)
		{
			lock (toBild)
			{
				lock (toWert)
				{
					toWert.TransformPoints(p);
				}
			}
			return p[0];
		}

		public void Draw(ref Graphics g)
		{
			center[0] = new PointF(0f, 0f);
			lock (toBild)
			{
				lock (toWert)
				{
					toBild.TransformPoints(center);
				}
			}
			StringFormat stringFormat = new StringFormat();
			stringFormat.Alignment = StringAlignment.Center;
			double num = 0.0;
			if (always_xaxe)
			{
				xaxeoffset = center[0].Y - (float)height + 25f + xaxeoffset_bild;
			}
			lock (g)
			{
				if (show_xaxe)
				{
					g.DrawLine(Pens.Black, Offset.X, center[0].Y - xaxeoffset, width, center[0].Y - xaxeoffset);
					double num2 = (double)((float)width - Offset.X) / ((double)xlen / xscal);
					int num3 = 0;
					double num4 = center[0].X;
					while (num4 < (double)width)
					{
						num3++;
						if (show_xscalierung)
						{
							if (num2 > 20.0)
							{
								g.DrawString(num.ToString(), fnt, fnt_brush_x, (float)num4, center[0].Y - xaxeoffset + 5f, stringFormat);
							}
							g.DrawLine(Pens.Black, (float)num4, center[0].Y - 2f - xaxeoffset, (float)num4, center[0].Y + 2f - xaxeoffset);
						}
						if (num != 0.0 && show_xraster)
						{
							g.DrawLine(p_raster, (float)num4, 0f, (float)num4, height);
						}
						num4 += num2;
						num = xscal * (double)num3;
					}
					num3 = 0;
					double num5 = center[0].X;
					while (num5 > (double)Offset.X)
					{
						if (num3 == 0)
						{
							num3++;
						}
						else
						{
							num3++;
							if (show_xscalierung)
							{
								if (num2 > 20.0)
								{
									g.DrawString(num.ToString(), fnt, fnt_brush_x, (float)num5, center[0].Y - xaxeoffset + 5f, stringFormat);
								}
								g.DrawLine(Pens.Black, (float)num5, center[0].Y - 2f - xaxeoffset, (float)num5, center[0].Y + 2f - xaxeoffset);
							}
							if (num != 0.0 && show_xraster)
							{
								g.DrawLine(p_raster, (float)num5, 0f, (float)num5, height);
							}
						}
						num5 -= num2;
						num = (0.0 - xscal) * (double)num3;
					}
					stringFormat.Alignment = StringAlignment.Far;
					g.DrawString(x_axetext, fnt, fnt_brush_x, BILD_WIDTH - 10, center[0].Y - xaxeoffset - (float)fnt.Height, stringFormat);
					stringFormat.Alignment = StringAlignment.Center;
				}
				if (always_yaxe)
				{
					yaxeoffset = yaxeoffset_bild;
				}
				if (show_yaxe)
				{
					stringFormat.Alignment = StringAlignment.Far;
					double num6 = (double)(height - 50) / ((double)ylen / yscal);
					stringFormat.Alignment = StringAlignment.Near;
					g.DrawString(y_axetext, fnt, fnt_brush, yaxeoffset - 10f, 7f, stringFormat);
					stringFormat.Alignment = StringAlignment.Far;
					string text = "";
					num = 0.0;
					double num7 = center[0].Y;
					while (num7 < (double)height)
					{
						if (show_yscalierung)
						{
							if (num6 >= 10.0)
							{
								if ((int)format < 5)
								{
									text = ConfigBase.StrStringFormat[(uint)format];
									string s = string.Format(text, Convert.ToUInt64(num));
									g.DrawString(s, fnt, fnt_brush, yaxeoffset, (float)num7 - 7f, stringFormat);
								}
								else if (format == ConfigBase.EStringFormat.e_Bin)
								{
									text = ConfigBase.StrStringFormat[(uint)format];
									string s2 = "";
									if (num >= 0.0)
									{
										s2 = string.Format(text, Convert.ToUInt64(num));
									}
									g.DrawString(s2, fnt, fnt_brush, yaxeoffset, (float)num7 - 7f, stringFormat);
								}
								else
								{
									g.DrawString(num.ToString(), fnt, fnt_brush, yaxeoffset, (float)num7 - 7f, stringFormat);
								}
							}
							g.DrawLine(p, yaxeoffset - 2f, (float)num7, yaxeoffset + 2f, (float)num7);
						}
						if (num != 0.0 && num != (double)ymin && show_yraster)
						{
							g.DrawLine(p_raster, Offset.X, (float)num7, width, (float)num7);
						}
						num7 += num6;
						num -= yscal;
					}
					num = 0.0;
					double num8 = center[0].Y;
					while (num8 >= (double)Offset.Y)
					{
						if (show_yscalierung)
						{
							if (num6 > 10.0)
							{
								if ((int)format < 5)
								{
									text = ConfigBase.StrStringFormat[(uint)format];
									string s3 = string.Format(text, Convert.ToUInt64(num));
									g.DrawString(s3, fnt, fnt_brush, yaxeoffset, (float)num8 - 7f, stringFormat);
								}
								else if (format == ConfigBase.EStringFormat.e_Bin)
								{
									text = ConfigBase.StrStringFormat[(uint)format];
									string s4 = "";
									if (num >= 0.0)
									{
										s4 = string.Format(text, Convert.ToUInt64(num));
									}
									g.DrawString(s4, fnt, fnt_brush, yaxeoffset, (float)num8 - 7f, stringFormat);
								}
								else
								{
									g.DrawString(num.ToString(), fnt, fnt_brush, yaxeoffset, (float)num8 - 7f, stringFormat);
								}
							}
							g.DrawLine(p, yaxeoffset - 2f, (float)num8, yaxeoffset + 2f, (float)num8);
						}
						if (show_yraster)
						{
							g.DrawLine(p_raster, Offset.X, (float)num8, width, (float)num8);
						}
						num8 -= num6;
						num += yscal;
					}
					g.DrawLine(p, yaxeoffset, Offset.Y, yaxeoffset, height - 25 + 2);
				}
			}
			p.DashStyle = DashStyle.Dash;
		}

		public void offsetWert(float x, float y)
		{
			Wert.Offset(x, y);
			lock (toBild)
			{
				lock (toWert)
				{
					toBild.Translate(0f - x, 0f - y);
					toWert = toBild.Clone();
					toWert.Invert();
				}
			}
			xmin += x;
			xmax += x;
			ymin += y;
			ymax += y;
		}

		public void zoom(float factor)
		{
			float num = xlen * factor;
			float num2 = xlen * factor;
			Wert.Offset(num, 0f - num2);
			Wert.Width -= num;
			Wert.Width -= num;
			Wert.Height += num2;
			Wert.Height += num2;
			lock (toBild)
			{
				lock (toWert)
				{
					toBild = (toWert = null);
					toBild = new Matrix(Wert, pp);
					toWert = toBild.Clone();
					toWert.Invert();
				}
			}
			xmin += num;
			xmax -= num;
			ymin += num2;
			ymax -= num2;
			xlen = Wert.Width;
			ylen = Math.Abs(Wert.Height);
			Autoscale();
		}

		private void updateMatrix()
		{
			Wert = new RectangleF(xmin, ymax, xmax - xmin, (ymax - ymin) * -1f);
			pp[1] = new PointF(width, pp[0].Y);
			pp[2] = new PointF(pp[0].X, height - 25);
			xlen = Wert.Width;
			ylen = Math.Abs(Wert.Height);
			lock (toBild)
			{
				lock (toWert)
				{
					toBild = (toWert = null);
					toBild = new Matrix(Wert, pp);
					toWert = toBild.Clone();
					toWert.Invert();
				}
			}
			Autoscale();
		}

		private void Autoscale()
		{
			double num = 0.0;
			int num2 = 0;
			int num3 = 0;
			xscal = xlen * 50f / (float)width;
			num = xscal;
			while ((int)num == 0)
			{
				num *= 10.0;
				num2++;
			}
			num = (int)num;
			num3 = (int)num % 5;
			if (num3 < 2)
			{
				xscal = (num - (double)num3) / Math.Pow(10.0, num2);
			}
			else
			{
				xscal = (num + (double)(5 - num3)) / Math.Pow(10.0, num2);
			}
			if (xscal == 0.0)
			{
				xscal = 1.0 / Math.Pow(10.0, num2);
			}
		}

		public bool isPoint(PointF point)
		{
			center[0] = new PointF(0f, 0f);
			lock (toBild)
			{
				lock (toWert)
				{
					toBild.TransformPoints(center);
				}
			}
			if (Math.Abs(point.X - yaxeoffset) < 4f)
			{
				return true;
			}
			if (Math.Abs(point.Y - (center[0].Y - xaxeoffset)) < 4f)
			{
				return true;
			}
			return false;
		}
	}
}
